package com.zingrow.common.utils;

import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
//import java.util.Collections;
//import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
//import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
//import org.bson.Document;
import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Key;
import org.mongodb.morphia.Morphia;
import org.mongodb.morphia.aggregation.Accumulator;
import org.mongodb.morphia.aggregation.AggregationPipeline;
import org.mongodb.morphia.aggregation.Group;
import org.mongodb.morphia.query.FindOptions;
import org.mongodb.morphia.query.MorphiaIterator;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.Sort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.mongodb.AggregationOptions;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
import com.zingrow.common.exception.NumberErrorException;
//import com.mongodb.client.MongoCollection;
//import com.mongodb.client.MongoDatabase;
import com.zingrow.web.entity.InformationDistribute;
import com.zingrow.web.report.base.Channel;
import com.zingrow.web.report.model.DimensionBbsRanking;
import com.zingrow.web.report.model.DimensionChannel;
import com.zingrow.web.report.model.DimensionDomain;
import com.zingrow.web.report.model.DimensionNewsRanking;
import com.zingrow.web.report.model.DimensionPlan;
import com.zingrow.web.report.model.DimensionPlanRanking;
import com.zingrow.web.report.model.DimensionWeiboRanking;
import com.zingrow.web.report.model.DimensionWeixinRanking;
import com.zingrow.web.report.utils.ReportUtils;

public class MongoHelper {
    Logger logger = LoggerFactory.getLogger(MongoHelper.class);
    public static MongoHelper instance = null;
    private Datastore datastore;
    private MongoClient mongoClient;
    private Splitter.MapSplitter mapSplitter = Splitter.onPattern(",|，").omitEmptyStrings().trimResults()
            .withKeyValueSeparator(":");
    // private Map<String, MongoDatabase> databaseInfos = new LinkedHashMap();
    // private Map<String, MongoCollection<Document>> collectionInfos = new
    // LinkedHashMap();
    private Morphia morphia = new Morphia();

    private MongoHelper() {
        FileInputStream fis = null;
        try {
            this.morphia.mapPackage("com.zingrow.web.entity");
            fis = new FileInputStream(
                    new File(MongoHelper.class.getResource("/").getPath(), "properties/mongo.properties"));

            Properties properties = new Properties();
            properties.load(fis);
            String databaseName = properties.getProperty("mongo_dbName");
            String hostList = properties.getProperty("mongo_host");
            // hostList = hostList+",172.1.8.12:20000";
            Map<String, String> serverMap = this.mapSplitter.split(hostList);
            List<ServerAddress> serverList = new ArrayList<>();
            if ((null != serverMap) && (!serverMap.isEmpty())) {
                for (Map.Entry<String, String> entry : serverMap.entrySet()) {
                    serverList.add(
                            new ServerAddress((String) entry.getKey(), Integer.parseInt((String) entry.getValue())));
                }
            }
            if ((serverList.size() > 0) && (StringUtils.isNotBlank(databaseName))) {
                MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
                builder.minConnectionsPerHost(10);
                builder.connectionsPerHost(10);
                builder.connectTimeout(60000);
                builder.socketTimeout(0);
                builder.maxWaitTime(60000);
                builder.threadsAllowedToBlockForConnectionMultiplier(5);
                builder.maxConnectionIdleTime(3600000);
                builder.maxConnectionLifeTime(7200000);
                builder.socketKeepAlive(true);
                this.mongoClient = new MongoClient(serverList, builder.build());
                this.datastore = this.morphia.createDatastore(this.mongoClient, StringUtils.strip(databaseName));
                this.datastore.ensureIndexes();
                this.logger.info("morphia连接池初始化完毕！");
            }
            if (null != fis) {
                try {
                    fis.close();
                } catch (Exception e) {
                    e.printStackTrace();
                    this.logger.error(e.getMessage());
                }
            }
            return;
        } catch (Exception e) {
            e.printStackTrace();
            this.logger.error(e.getMessage());
        } finally {
            if (null != fis) {
                try {
                    fis.close();
                } catch (Exception e) {
                    e.printStackTrace();
                    this.logger.error(e.getMessage());
                }
            }
        }
    }

    public static MongoHelper getInstance() {
        if (null == instance) {
            instance = new MongoHelper();
        }
        return instance;
    }

    private Datastore getDatastore() {
        return getInstance().datastore;
    }

    // private MongoClient getMongoClient() {
    // return getInstance().mongoClient;
    // }

    public boolean insert(Object object) {
        try {
            Key<Object> key = getDatastore().save(object);
            if ((null != key) && (null != key.getId())) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * APP用户收藏查询的底层实现
     * 
     * @param entity
     * @param ifmids
     * @param articleId
     * @param timestamp
     * @return
     */
    public List<InformationDistribute> queryUserEnshrine(Class<?> entity, List<String> ifmids, List<String> articleId,
            Long timestamp) {
        List<InformationDistribute> list = new ArrayList<>();
        Datastore datastore = getDatastore();
        Query<?> query = datastore.createQuery(entity);
        query.and(query.criteria("ifmId").in(ifmids), query.criteria("articleId").in(articleId));
        AggregationPipeline pipeline = this.datastore.createAggregation(entity).match(query).group(
                Group.id(Group.grouping("articleId")), Group.grouping("articleId", Group.first("articleId")),
                Group.grouping("releaseTime", Group.first("releaseTime")),
                Group.grouping("ifmId", Group.first("ifmId")), Group.grouping("groupId", Group.first("groupId")),
                Group.grouping("articleType", Group.first("articleType")),
                Group.grouping("title", Group.first("title")), Group.grouping("url", Group.first("url")),
                Group.grouping("readNumb", Group.first("readNumb")), Group.grouping("source", Group.first("source")),
                Group.grouping("websiteName", Group.first("websiteName")),
                Group.grouping("pointNum", Group.first("pointNum")),
                Group.grouping("weiboReprintNumb", Group.first("weiboReprintNumb")),
                Group.grouping("weiboCommentNumb", Group.first("weiboCommentNumb")),
                Group.grouping("weiboIsForward", Group.first("weiboIsForward")),
                Group.grouping("isCollection", Group.first("isCollection")),
                Group.grouping("weiboType", Group.first("weiboType")),
                Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                Group.grouping("timestamp", Group.first("timestamp")),
                Group.grouping("weiboType", Group.first("weiboType")),
                Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                Group.grouping("weiboSourceContent", Group.first("weiboSourceContent")),
                Group.grouping("weiboBlogger", Group.first("weiboBlogger")),
                Group.grouping("weiboContent", Group.first("weiboContent")),
                Group.grouping("sort_timestamp", Group.first("sort_timestamp")),
                Group.grouping("author", Group.first("author")));
        if ((null != timestamp) && (timestamp.longValue() > 0L)) {
            query.filter("sort_timestamp <", timestamp);
            pipeline.match(query).sort(Sort.descending("sort_timestamp")).limit(10);
        } else {
            pipeline.sort(Sort.descending("sort_timestamp")).limit(10);
        }
        Iterator<?> iterator = pipeline.aggregate(entity, AggregationOptions.builder().allowDiskUse(true).build());
        while (iterator.hasNext()) {
            InformationDistribute person = (InformationDistribute) iterator.next();
            if (!Strings.isNullOrEmpty(person.getId())) {
                person.setReprintNumb(person.getReprintNumb());
                person.setId("");
                list.add(person);
            }
        }
        return list;
    }

    /**
     * APP查询的底层实现
     * 
     * @param entity
     * @param ifmid
     * @param timestamp
     * @return
     */
    public List<InformationDistribute> queryByIDlastTimestamp(Class<?> entity, String ifmid, Long timestamp) {
        List<InformationDistribute> list = new ArrayList<>();
        List<String> tempGroupids = new ArrayList<String>();
        int limitNum = 2000;
        int maxlimit = 2000;
        int pagesize = 10;
        AggregationPipeline pipeline = null;
        // long startTime = System.currentTimeMillis(); // 获取开始时间
        try {
            for (int i = limitNum; i <= limitNum * 3; i = i * 2) {
                Query<?> query = getDatastore().createQuery(entity);
                Query<?> query3 = getDatastore().createQuery(entity);
                query.criteria("ifmId").equal(ifmid);
                // query.order(Sort.descending("releaseTime"));
                if ((null != timestamp) && (timestamp.longValue() > 0L)) {
                    query3.criteria("sort_timestamp").lessThan(timestamp);
                } else {
                    // query3.filter("sort_timestamp <", startTime + 1);
                }
                pipeline = this.datastore.createAggregation(entity).match(query)
                        .sort(Sort.descending("sort_timestamp"));
                if (i <= maxlimit) {
                    pipeline.limit(i);
                }
                pipeline.group("groupId", Group.grouping("releaseTime", Group.first("releaseTime")),
                        Group.grouping("sort_timestamp", Group.first("sort_timestamp")),
                        Group.grouping("groupId", Group.first("groupId"))).match(query3)
                        .sort(Sort.descending("sort_timestamp")).limit(pagesize);
//                logger.debug("APP查询GroupId:"+pipeline.toString());
                Iterator<?> iterator = pipeline.aggregate(entity,
                        AggregationOptions.builder().allowDiskUse(true).build());
                
                while (iterator.hasNext()) {
                    InformationDistribute information = (InformationDistribute) iterator.next();
                    tempGroupids.add(information.getGroupId());
                }
                if (tempGroupids.size() >= pagesize) {
                    break;
                }
            }

            Query<?> query1 = getDatastore().createQuery(entity);
            query1.criteria("ifmId").equal(ifmid);
            query1.field("groupId").in(tempGroupids);
            // query1.order(Sort.descending("releaseTime"));
            AggregationPipeline pipelineList = this.datastore.createAggregation(entity).match(query1)
                    .sort(Sort.descending("sort_timestamp"))
                    .group(Group.id(Group.grouping("groupId")), Group.grouping("groupId", Group.first("groupId")),
                            Group.grouping("releaseTime", Group.first("releaseTime")),
                            Group.grouping("sort_timestamp", Group.first("sort_timestamp")),
                            Group.grouping("ifmId", Group.first("ifmId")),
                            Group.grouping("articleId", Group.first("articleId")),
                            Group.grouping("articleType", Group.first("articleType")),
                            Group.grouping("title", Group.first("title")), Group.grouping("url", Group.first("url")),
                            Group.grouping("readNumb", Group.first("readNumb")),
                            Group.grouping("source", Group.first("source")),
                            Group.grouping("websiteName", Group.first("websiteName")),
                            Group.grouping("pointNum", Group.first("pointNum")),
                            Group.grouping("weiboReprintNumb", Group.first("weiboReprintNumb")),
                            Group.grouping("weiboCommentNumb", Group.first("weiboCommentNumb")),
                            Group.grouping("weiboIsForward", Group.first("weiboIsForward")),
                            Group.grouping("isCollection", Group.first("isCollection")),
                            Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                            Group.grouping("timestamp", Group.first("timestamp")),
                            Group.grouping("weiboType", Group.first("weiboType")),
                            Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                            Group.grouping("weiboSourceContent", Group.first("weiboSourceContent")),
                            Group.grouping("weiboBlogger", Group.first("weiboBlogger")),
                            Group.grouping("weiboContent", Group.first("weiboContent")),
                            Group.grouping("author", Group.first("author")),
                            Group.grouping("reprintNumb", new Accumulator("$sum", 1)))
                    .sort(Sort.descending("sort_timestamp"));
//            logger.debug("APP聚合GroupId:"+pipelineList.toString());
            Iterator<?> iteratorList = pipelineList.aggregate(entity,
                    AggregationOptions.builder().allowDiskUse(true).build());
            while (iteratorList.hasNext()) {
                InformationDistribute person = (InformationDistribute) iteratorList.next();
                if (!Strings.isNullOrEmpty(person.getId())) {
                    person.setReprintNumb(person.getReprintNumb());
                    person.setId("");
                    list.add(person);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            this.logger.error(e.getMessage());
        }
        // long endTime = System.currentTimeMillis();
        // System.out.println(endTime - startTime + "ms");
        return list;
    }

    /**
     * 已过时的方法，没有被调用
     * 
     * @param entity
     * @param ifmid
     * @return
     */
    public List<InformationDistribute> queryInitById(Class<?> entity, String ifmid) {
        List<InformationDistribute> list = new ArrayList<>();
        try {
            Query<?> query = getDatastore().createQuery(entity);
            query.criteria("ifmId").equal(ifmid);
            // AggregationPipeline pipeline =
            // this.datastore.createAggregation(entity).match(query)
            // .sort(new Sort[] { Sort.descending("sort_timestamp")
            // }).limit(10);
            MorphiaIterator<?, ?> morph = query.order(Sort.descending("sort_timestamp"))
                    .fetch(new FindOptions().limit(10));
            Iterator<?> iterator = morph.iterator();
            if (iterator.hasNext()) {
                while (iterator.hasNext()) {
                    InformationDistribute person = (InformationDistribute) iterator.next();
                    list.add(person);
                }
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
            this.logger.error(e.getMessage());
        }
        return list;
    }

    /**
     * APP查询相似转载的方法底层实现
     * 
     * @param entity
     * @param ifmId
     * @param groupId
     * @param timestamp
     * @return
     */
    public List<InformationDistribute> queryLikeByGroupId(Class<?> entity, String ifmId, String groupId,
            Long timestamp) {
        List<InformationDistribute> list = new ArrayList<>();

        Query<?> query = getDatastore().createQuery(entity);
        query.criteria("ifmId").equal(ifmId).criteria("groupId").equal(groupId);
        AggregationPipeline pipeline = this.datastore.createAggregation(entity).match(query).group(
                Group.id(Group.grouping("articleId")), Group.grouping("articleId", Group.first("articleId")),
                Group.grouping("releaseTime", Group.first("releaseTime")),
                Group.grouping("ifmId", Group.first("ifmId")), Group.grouping("groupId", Group.first("groupId")),
                Group.grouping("articleType", Group.first("articleType")),
                Group.grouping("title", Group.first("title")), Group.grouping("url", Group.first("url")),
                Group.grouping("readNumb", Group.first("readNumb")), Group.grouping("source", Group.first("source")),
                Group.grouping("websiteName", Group.first("websiteName")),
                Group.grouping("pointNum", Group.first("pointNum")),
                Group.grouping("weiboReprintNumb", Group.first("weiboReprintNumb")),
                Group.grouping("weiboCommentNumb", Group.first("weiboCommentNumb")),
                Group.grouping("weiboIsForward", Group.first("weiboIsForward")),
                Group.grouping("isCollection", Group.first("isCollection")),
                Group.grouping("weiboType", Group.first("weiboType")),
                Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                Group.grouping("timestamp", Group.first("timestamp")),
                Group.grouping("weiboType", Group.first("weiboType")),
                Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                Group.grouping("weiboSourceContent", Group.first("weiboSourceContent")),
                Group.grouping("weiboBlogger", Group.first("weiboBlogger")),
                Group.grouping("weiboContent", Group.first("weiboContent")),
                Group.grouping("sort_timestamp", Group.first("sort_timestamp")),
                Group.grouping("author", Group.first("author")));
        if ((null != timestamp) && (timestamp.longValue() > 0L)) {
            query.filter("sort_timestamp >", timestamp);
            pipeline.match(query).sort(Sort.ascending("sort_timestamp")).limit(10);
        } else {
            pipeline.sort(Sort.ascending("sort_timestamp")).limit(10);
        }
        Iterator<?> iterator = pipeline.aggregate(entity, AggregationOptions.builder().allowDiskUse(true).build());
        while (iterator.hasNext()) {
            InformationDistribute person = (InformationDistribute) iterator.next();
            if (!Strings.isNullOrEmpty(person.getId())) {
                person.setReprintNumb(person.getReprintNumb());
                person.setId("");
                list.add(person);
            }
        }
        return list;
    }

    /**
     * 判断单条信息是否被收藏了
     * 
     * @param entity
     * @param articleId
     * @param ifmId
     * @return
     */
    public InformationDistribute queryContentByArticleId(Class<?> entity, String articleId, String ifmId) {
        InformationDistribute distribute = new InformationDistribute();
        Query<?> query = getDatastore().createQuery(entity);
        query.and(query.criteria("ifmId").equal(ifmId), query.criteria("articleId").equal(articleId));
        query.fetch(new FindOptions().limit(1));
        if (null != query.get()) {
            distribute = (InformationDistribute) query.get();
            return distribute;
        }
        return distribute;
    }
    /**
     * 判断单条信息是否被收藏了
     * 
     * @param entity
     * @param _id
     * @return
     */
    public InformationDistribute queryContentById(Class<?> entity, String _id) {
        InformationDistribute distribute = new InformationDistribute();
        Query<?> query = getDatastore().createQuery(entity);
        query.and(query.criteria("_id").equal(_id));
        query.fetch(new FindOptions().limit(1));
        if (null != query.get()) {
            distribute = (InformationDistribute) query.get();
            return distribute;
        }
        return distribute;
    }

    /**
     * 用户搜索
     * 
     * @param entity
     * @param id
     */
    public List<InformationDistribute> queryKewWorkLike(Class<?> entity, String KewWord, Long timestamp,
            List<String> ifmIds) {
        List<InformationDistribute> list = new ArrayList<>();
        Query<?> query = getDatastore().createQuery(entity);
        query.field("ifmId").in(ifmIds);
        query.or(query.criteria("title").containsIgnoreCase(KewWord),
                query.criteria("weiboContent").containsIgnoreCase(KewWord),
                query.criteria("weiboSourceContent").containsIgnoreCase(KewWord));
        AggregationPipeline pipeline = this.datastore.createAggregation(entity).match(query).group(
                Group.id(Group.grouping("articleId")), Group.grouping("groupId", Group.first("groupId")),
                Group.grouping("releaseTime", Group.first("releaseTime")),
                Group.grouping("ifmId", Group.first("ifmId")), Group.grouping("articleId", Group.first("articleId")),
                Group.grouping("articleType", Group.first("articleType")),
                Group.grouping("title", Group.first("title")), Group.grouping("url", Group.first("url")),
                Group.grouping("readNumb", Group.first("readNumb")), Group.grouping("source", Group.first("source")),
                Group.grouping("websiteName", Group.first("websiteName")),
                Group.grouping("pointNum", Group.first("pointNum")),
                Group.grouping("weiboReprintNumb", Group.first("weiboReprintNumb")),
                Group.grouping("weiboCommentNumb", Group.first("weiboCommentNumb")),
                Group.grouping("weiboIsForward", Group.first("weiboIsForward")),
                Group.grouping("isCollection", Group.first("isCollection")),
                Group.grouping("weiboType", Group.first("weiboType")),
                Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                Group.grouping("timestamp", Group.first("timestamp")),
                Group.grouping("weiboType", Group.first("weiboType")),
                Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                Group.grouping("weiboSourceContent", Group.first("weiboSourceContent")),
                Group.grouping("weiboBlogger", Group.first("weiboBlogger")),
                Group.grouping("weiboContent", Group.first("weiboContent")),
                Group.grouping("sort_timestamp", Group.first("sort_timestamp")),
                Group.grouping("author", Group.first("author")));
        if ((null != timestamp) && (timestamp.longValue() > 0L)) {
            query.filter("sort_timestamp <", timestamp);
            pipeline.match(query).sort(Sort.descending("sort_timestamp")).limit(10);
        } else {
            pipeline.sort(Sort.descending("sort_timestamp")).limit(10);
        }
        Iterator<?> iterator = pipeline.aggregate(entity, AggregationOptions.builder().allowDiskUse(true).build());
        if (iterator.hasNext()) {
            while (iterator.hasNext()) {
                InformationDistribute person = (InformationDistribute) iterator.next();
                list.add(person);
            }
        }

        return list;
    }

    public void delete(Class<?> entity, ObjectId id) {
        getDatastore().delete(entity, id);
    }

    public InformationDistribute queryContentBy_Id(Class<?> entity, String _id) {
        InformationDistribute informationDistribute = new InformationDistribute();
        Query<?> query = getDatastore().createQuery(entity);
        query.criteria("_id").equal(_id);
        Iterator<?> iterator = query.iterator();
        if (iterator.hasNext()) {
            InformationDistribute person = (InformationDistribute) iterator.next();
            informationDistribute.setContent(StringUtils.isNotBlank(person.getContent())
                    ? StringUtil.stringFilter(person.getContent().replaceAll("<.*?em.*?>", "")) : "");
            informationDistribute.setWeiboContent(StringUtils.isNotBlank(person.getWeiboContent())
                    ? StringUtil.stringFilter(person.getWeiboContent().replaceAll("<.*?em.*?>", "")) : "");
        }
        return informationDistribute;
    }

    public Set<InformationDistribute> queryByGroupId(Class<?> entity, String groupId, Date startTime, Date endTime,
            Integer ifmId) {
        List<InformationDistribute> list = new ArrayList<InformationDistribute>();
        Query<?> query = getDatastore().createQuery(entity);
        query.criteria("groupId").equal(groupId);
        if (null != startTime) 
        {
            query.criteria("releaseTime").greaterThanOrEq(startTime);
        }
        if (null != endTime) {
            query.criteria("releaseTime").lessThan(endTime);
        }
        if (null != ifmId) {
            query.criteria("ifmId").equal(ifmId);
        }
        Iterator<?> iterator = query.iterator();
        if (iterator.hasNext()) {
            InformationDistribute person = (InformationDistribute) iterator.next();
            list.add(person);
        }
        Set<InformationDistribute> set = new HashSet<InformationDistribute>(list);
        return set;
    }
    public Set<InformationDistribute> queryByGroupId(Class<?> entity, List<String> groupId, Date startTime, Date endTime,
            List<Integer> ifmId) {
        List<InformationDistribute> list = new ArrayList<InformationDistribute>();
        for(int i=0;i<groupId.size();i++)
        {
        Query<?> query = getDatastore().createQuery(entity);
        query.criteria("groupId").equal(groupId.get(i));
        if (null != startTime) {
            query.criteria("releaseTime").greaterThanOrEq(startTime);
        }
        if (null != endTime) {
            query.criteria("releaseTime").lessThan(endTime);
        }
        //ifmId为一个方案id list不用根据方案id查询
       /* if (null != ifmId) {
        	System.out.println("进入ifmId");
            query.criteria("ifmId").equal(ifmId.get(i));
        }*/
        Iterator<?> iterator = query.iterator();
        if (iterator.hasNext()) {
            InformationDistribute person = (InformationDistribute) iterator.next();
            list.add(person);
            
        }
        }
        Set<InformationDistribute> set = new HashSet<InformationDistribute>(list);
        return set;
    }

    // -----------------------------------维度统计------------------------------------------------------------------------------------------

    /**
     * 站点维度信息统计
     * 
     * @param entity
     * @param ifmIds
     * @param startTime
     * @param endTime
     * @return
     * @throws NumberErrorException
     */
    public List<DimensionDomain> StatisticsDomain(Class<?> entity, List<Integer> ifmIds, Long startTime, Long endTime,
            Integer cycleNum) throws NumberErrorException {
        List<DimensionDomain> DimensionDomainList = new ArrayList<>();// 站点维度
        int fabushu = 0;// 每个站点的发布数
        int reprintNum = 0;// 转载数
        Date fabuTime = new Date(startTime);// 发布时间（count_time）
        Date thisTime = new Date();// 当前的时间作为统计时间（update_time）
        // 循环方案ID
        for (Integer ifmId : ifmIds) {
            List<DimensionDomain> DimensionDomainList1 = new ArrayList<>();// 站点维度
            Query<?> query = getDatastore().createQuery(entity);
            query.criteria("ifmId").equal(ifmId.toString());
            query.criteria("sort_timestamp").greaterThanOrEq(startTime);// 大于等于startTime
            query.criteria("sort_timestamp").lessThan(endTime);// 小于endTime
            query.criteria("websiteName").notEqual(null);// 过滤站点字段为空的信息
            query.criteria("websiteName").notEqual("");// 过滤站点字段为空的信息

            // 聚合groupId,站点。
            AggregationPipeline pipelineList1 = this.datastore.createAggregation(entity).match(query)
                    .group(Group.id(Group.grouping("groupId")), Group.grouping("groupId", Group.first("groupId")),
                            Group.grouping("websiteName", Group.first("websiteName")))
                    .group(Group.id(Group.grouping("websiteName")),
                            Group.grouping("websiteName", Group.first("websiteName")),
                            Group.grouping("count", new Accumulator("$sum", 1)))
                    .sort(Sort.descending("count")).limit(10);
            Iterator<?> iteratorList1 = pipelineList1.aggregate(entity,
                    AggregationOptions.builder().allowDiskUse(true).build());
            int i = 0;// 用于生成数据库ID
            // 迭代站点
            while (iteratorList1.hasNext()) {
                InformationDistribute domainName = (InformationDistribute) iteratorList1.next();
                Query<?> query2 = getDatastore().createQuery(entity);// 必须使用新Query
                query2.criteria("ifmId").equal(ifmId.toString());
                query2.criteria("sort_timestamp").greaterThanOrEq(startTime);
                query2.criteria("sort_timestamp").lessThan(endTime);
                query2.criteria("websiteName").equal(domainName.getWebsiteName());
                fabushu = (int) query2.count();
                query2.criteria("original").equal(false);
                reprintNum = (int) query2.count();
                DimensionDomain dd = new DimensionDomain();// 站点维度对象
                dd.setPlanId(ifmId);
                dd.setOriginalNum(fabushu - reprintNum);// 原创数=发布数-转载数
                dd.setReprintNum(reprintNum);
                dd.setPublish_num(fabushu);
                dd.setDomainHost("");
                dd.setDomainName(domainName.getWebsiteName());
                dd.setCountTime(fabuTime);
                dd.setUpdateTime(thisTime);
                DimensionDomainList1.add(dd);
            }
            logger.info(String.format("统计到日期：%s,方案：%s原创站点%s个", dateFormat.format(fabuTime), ifmId,
                    DimensionDomainList1.size()));
            for (DimensionDomain dimensionDomain : DimensionDomainList1) {
                i++;
                dimensionDomain.setId(ReportUtils.buildId(fabuTime, ifmId, i, cycleNum));// 站点表的主键ID规则
                DimensionDomainList.add(dimensionDomain);
            }
        }
        return DimensionDomainList;
    }

    /**
     * 渠道维度
     * 
     * @param entity
     * @param ifmIds
     * @param startTime
     * @param endTime
     * @return
     * @throws NumberErrorException
     */
    public List<DimensionChannel> StatisticsChannel(Class<?> entity, List<Integer> ifmIds, Long startTime, Long endTime)
            throws NumberErrorException {
        int reprintNum = 0;// 转载数
        int fabushu = 0;// 每个渠道的发布数
        Date fabuTime = new Date(startTime);
        Date thisTime = new Date();
        List<DimensionChannel> DimensionChannelList = new ArrayList<DimensionChannel>();// 渠道维度
        List<String> articleTypeList = new ArrayList<String>();
        articleTypeList.add("News");
        articleTypeList.add("BBS");
        articleTypeList.add("WeiXin");
        articleTypeList.add("Micro");
        // 循环方案ID
        for (Integer ifmId : ifmIds) {
            int i = 0;// 生成渠道表ID所需规则变量
            // 循环渠道
            for (String articleType : articleTypeList) {
                switch (articleType) {
                case "News":
                    i = Channel.NEWS.getIndex();
                    break;
                case "WeiXin":
                    i = Channel.WEIXIN.getIndex();
                    break;
                case "Micro":
                    i = Channel.WEIBO.getIndex();
                    break;
                case "BBS":
                    i = Channel.BBS.getIndex();
                    break;
                }
                Query<?> query = getDatastore().createQuery(entity);
                query.criteria("ifmId").equal(ifmId.toString());
                query.criteria("sort_timestamp").greaterThanOrEq(startTime);
                query.criteria("sort_timestamp").lessThan(endTime);
                query.criteria("articleType").equal(articleType);// 匹配渠道条件

                // AggregationPipeline pipelineList1 =
                // this.datastore.createAggregation(entity).match(query)
                // .group(Group.id(Group.grouping("_id")),Group.grouping("initcount",new
                // Accumulator("$first", 1)))
                // .group(Group.id(Group.grouping("_id")),Group.grouping("count",
                // Group.sum("initcount")));
                // Iterator<?> iteratorList1 = pipelineList1.aggregate(entity,
                // AggregationOptions.builder().allowDiskUse(true).build());
                // long totalcount = 0;
                // while (iteratorList1.hasNext()) {
                // InformationDistribute person = (InformationDistribute)
                // iteratorList1.next();
                // totalcount = person.getCount();
                // }

                fabushu = (int) query.count();
                query.criteria("original").equal(false);
                reprintNum = (int) query.count();
                DimensionChannel dimensionChannel = new DimensionChannel();// 渠道维度对象
                Long id = ReportUtils.buildId(fabuTime, ifmId, i);// 默认生成的每日ID
                dimensionChannel.setId(id);
                dimensionChannel.setPlanId(ifmId);
                dimensionChannel.setOriginalNum(fabushu - reprintNum);// 原创数=发布数-转载数
                dimensionChannel.setReprintNum(reprintNum);// 转载数
                dimensionChannel.setPublish_num(fabushu);
                dimensionChannel.setChannelType(i);
                dimensionChannel.setChannelName(articleType);
                dimensionChannel.setCountTime(fabuTime);
                dimensionChannel.setUpdateTime(thisTime);
                DimensionChannelList.add(dimensionChannel);

            }
        }
        return DimensionChannelList;
    }

    /**
     * 方案统计维度
     * 
     * @param entity
     * @param ifmIds
     * @param startTime
     * @param endTime
     * @return
     * @throws NumberErrorException
     */
    public List<DimensionPlan> StatisticsDimensionPlan(Class<?> entity, List<Integer> ifmIds, Long startTime,
            Long endTime) throws NumberErrorException {
        List<DimensionPlan> DimensionPlanList = new ArrayList<DimensionPlan>();// 方案转载维度
        int reprintNum = 0;// 转载数
        int fabushu = 0;// 每个方案的发布数
        Date fabuTime = new Date(startTime);
        Date thisTime = new Date();
        for (Integer ifmId : ifmIds) {
            Query<?> query = getDatastore().createQuery(entity);
            query.criteria("ifmId").equal(ifmId.toString());
            query.criteria("sort_timestamp").greaterThanOrEq(startTime);
            query.criteria("sort_timestamp").lessThan(endTime);
            fabushu = (int) query.count();
            query.criteria("original").equal(false);
            reprintNum = (int) query.count();
            Long id = ReportUtils.buildId(fabuTime, ifmId, 1);// 默认生成的每日ID
            DimensionPlan dimensionPlan = new DimensionPlan();// 方案统计维度对象
            dimensionPlan.setId(id);
            dimensionPlan.setPlanId(ifmId);
            dimensionPlan.setOriginalNum(fabushu - reprintNum);
            dimensionPlan.setReprintNum(reprintNum);
            dimensionPlan.setPublish_num(fabushu);
            dimensionPlan.setCountTime(fabuTime);
            dimensionPlan.setUpdateTime(thisTime);
            DimensionPlanList.add(dimensionPlan);
        }

        return DimensionPlanList;
    }

    /**
     * 方案详细排行
     * 
     * @param entity
     * @param ifmIds
     * @param startTime
     * @param endTime
     * @return
     * @throws NumberErrorException
     */
    public List<DimensionPlanRanking> StatisticsPlanRanking(Class<?> entity, List<Integer> ifmIds, Long startTime,
            Long endTime) throws NumberErrorException {
        List<DimensionPlanRanking> DimensionPlanRankingList = new ArrayList<DimensionPlanRanking>();// 方案转载排行维度
        String WeiboContent = "";
        String WeibosourContent = "";
        Date fabuTime = new Date(startTime);
        Date thisTime = new Date();
        // 循环方案ID
        for (Integer ifmId : ifmIds) {
            Query<?> query = getDatastore().createQuery(entity);
            query.criteria("ifmId").equal(ifmId.toString());
            query.criteria("sort_timestamp").greaterThanOrEq(startTime);
            query.criteria("sort_timestamp").lessThan(endTime);
            // 聚合groupId取最热10条
            AggregationPipeline pipelineList = this.datastore.createAggregation(entity).match(query)
                    .group(Group.id(Group.grouping("groupId")), Group.grouping("groupId", Group.first("groupId")),
                            Group.grouping("releaseTime", Group.first("releaseTime")),
                            Group.grouping("sort_timestamp", Group.first("sort_timestamp")),
                            Group.grouping("ifmId", Group.first("ifmId")),
                            Group.grouping("articleId", Group.first("articleId")),
                            Group.grouping("articleType", Group.first("articleType")),
                            Group.grouping("title", Group.first("title")), Group.grouping("url", Group.first("url")),
                            Group.grouping("source", Group.first("source")),
                            Group.grouping("websiteName", Group.first("websiteName")),
                            Group.grouping("readNumb", Group.first("readNumb")),
                            Group.grouping("pointNum", Group.first("pointNum")),
                            Group.grouping("weiboReprintNumb", Group.first("weiboReprintNumb")),
                            Group.grouping("weiboCommentNumb", Group.first("weiboCommentNumb")),
                            Group.grouping("weiboIsForward", Group.first("weiboIsForward")),
                            Group.grouping("isCollection", Group.first("isCollection")),
                            Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                            Group.grouping("timestamp", Group.first("timestamp")),
                            Group.grouping("weiboType", Group.first("weiboType")),
                            Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                            Group.grouping("weiboSourceContent", Group.first("weiboSourceContent")),
                            Group.grouping("weiboBlogger", Group.first("weiboBlogger")),
                            Group.grouping("weiboContent", Group.first("weiboContent")),
                            Group.grouping("author", Group.first("author")),
                            Group.grouping("domainName", Group.first("domainName")),
                            Group.grouping("reprintNumb", new Accumulator("$sum", 1)))
                    .sort(Sort.descending("reprintNumb")).limit(10);
            Iterator<?> iteratorList = pipelineList.aggregate(entity,
                    AggregationOptions.builder().allowDiskUse(true).build());
            int i = 0;
            while (iteratorList.hasNext()) {
                InformationDistribute person = (InformationDistribute) iteratorList.next();
                i++;
                Query<?> query2 = getDatastore().createQuery(entity);
                query2.criteria("ifmId").equal(ifmId.toString());
                query2.criteria("sort_timestamp").greaterThanOrEq(startTime);
                query2.criteria("sort_timestamp").lessThan(endTime);
                query2.criteria("articleId").equal(person.getArticleId());
                InformationDistribute s = (InformationDistribute) query2.get();
                DimensionPlanRanking dimensionPlanRanking = new DimensionPlanRanking();
                Long id = ReportUtils.buildId(fabuTime, ifmId, i);// 默认生成的每日ID
                dimensionPlanRanking.setId(id);
                dimensionPlanRanking.setPlanId(ifmId);
                dimensionPlanRanking.setDataId(s.getId());
                if (StringUtils.isNotBlank(person.getTitle()) && !"None".equalsIgnoreCase(person.getTitle())) {
                    dimensionPlanRanking.setDataTitle(StringUtil.stringFilter(person.getTitle()));
                } else if (StringUtils.isNotBlank(person.getWeiboSourceContent())
                        && !"None".equalsIgnoreCase(person.getWeiboSourceContent())) {
                    WeibosourContent = person.getWeiboSourceContent().replaceAll("<.*?em.*?>", "");
                    WeibosourContent = StringUtil.stringFilter(WeibosourContent);
                    dimensionPlanRanking.setDataTitle(WeibosourContent);
                } else if (StringUtils.isNotBlank(person.getWeiboContent())
                        && !"None".equalsIgnoreCase(person.getWeiboContent())) {
                    WeiboContent = person.getWeiboContent().replaceAll("<.*?em.*?>", "");
                    WeiboContent = StringUtil.stringFilter(WeiboContent);
                    dimensionPlanRanking.setDataTitle(WeiboContent);
                }
                dimensionPlanRanking.setDataUrl(person.getUrl());
                if (StringUtils.isNotBlank(person.getDomainName())) {
                    dimensionPlanRanking.setDomainName(person.getDomainName());
                } else {
                    dimensionPlanRanking.setDomainName(
                            StringUtils.isNotBlank(person.getWebsiteName()) ? person.getWebsiteName() : "微博");
                }
                dimensionPlanRanking.setReprintNum(person.getReprintNumb() - 1);// 转载数
                if (StringUtils.isNotBlank(person.getAuthor())) {
                    dimensionPlanRanking.setDataAuthor(person.getAuthor());
                } else if (StringUtils.isNotBlank(person.getWebsiteName())) {
                    dimensionPlanRanking.setDataAuthor(person.getWebsiteName());
                } else if (StringUtils.isNotBlank(person.getWeiboBlogger())) {
                    dimensionPlanRanking.setDataAuthor(person.getWeiboBlogger());
                } else {
                    dimensionPlanRanking.setDataAuthor(StringUtils.isNotBlank(person.getWeiboSourceBlogger())
                            ? person.getWeiboSourceBlogger() : "");
                }
                dimensionPlanRanking.setPublishTime(person.getReleaseTime());
                dimensionPlanRanking.setCountTime(fabuTime);
                dimensionPlanRanking.setUpdateTime(thisTime);
                DimensionPlanRankingList.add(dimensionPlanRanking);
            }
        }

        return DimensionPlanRankingList;
    }

    /**
     * 方案新闻详细排行
     * 
     * @param entity
     * @param ifmIds
     *            Integer类型的方案ID集合
     * @param startTime
     *            开始时间
     * @param endTime
     *            结束时间
     * @return 方案信息排行对象集合
     * @throws NumberErrorException
     */
    public List<DimensionNewsRanking> StatisticsNewsRanking(Class<?> entity, List<Integer> ifmIds, Long startTime,
            Long endTime) throws NumberErrorException {
        List<DimensionNewsRanking> DimensionNewsRankingList = new ArrayList<DimensionNewsRanking>();// 方案新闻转载排行维度
        Date fabuTime = new Date(startTime);
        Date thisTime = new Date();
        // 循环方案ID
        for (Integer ifmId : ifmIds) {
            Query<?> query = getDatastore().createQuery(entity);
            query.criteria("ifmId").equal(ifmId.toString());
            query.criteria("articleType").equal("News");
            query.criteria("sort_timestamp").greaterThanOrEq(startTime);
            query.criteria("sort_timestamp").lessThan(endTime);
            // 聚合groupId取最热10条
            AggregationPipeline pipelineList = this.datastore.createAggregation(entity).match(query)
                    .group(Group.id(Group.grouping("groupId")), Group.grouping("groupId", Group.first("groupId")),
                            Group.grouping("articleId", Group.first("articleId")),
                            Group.grouping("releaseTime", Group.first("releaseTime")),
                            Group.grouping("title", Group.first("title")), Group.grouping("url", Group.first("url")),
                            Group.grouping("websiteName", Group.first("websiteName")),
                            Group.grouping("author", Group.first("author")),
                            Group.grouping("domainName", Group.first("domainName")),
                            Group.grouping("reprintNumb", new Accumulator("$sum", 1)))
                    .sort(Sort.descending("reprintNumb")).limit(10);
            Iterator<?> iteratorList = pipelineList.aggregate(entity,
                    AggregationOptions.builder().allowDiskUse(true).build());
            int i = 0;
            while (iteratorList.hasNext()) {
                InformationDistribute person = (InformationDistribute) iteratorList.next();
                i++;
                Query<?> query2 = getDatastore().createQuery(entity);
                query2.criteria("ifmId").equal(ifmId.toString());
                query2.criteria("sort_timestamp").greaterThanOrEq(startTime);
                query2.criteria("sort_timestamp").lessThan(endTime);
                query2.criteria("articleId").equal(person.getArticleId());
                InformationDistribute s = (InformationDistribute) query2.get();
                DimensionNewsRanking dimensionNewsRanking = new DimensionNewsRanking();
                Long id = ReportUtils.buildId(fabuTime, ifmId, i);// 默认生成的每日ID
                dimensionNewsRanking.setId(id);
                dimensionNewsRanking.setPlanId(ifmId);
                dimensionNewsRanking.setDataId(s.getId());
                dimensionNewsRanking.setDataTitle(StringUtil.stringFilter(person.getTitle()));
                dimensionNewsRanking.setDataUrl(person.getUrl());
                if (StringUtils.isNotBlank(person.getWebsiteName())) {
                    dimensionNewsRanking.setDomainName(person.getWebsiteName());
                } else {
                    dimensionNewsRanking.setDomainName(
                            StringUtils.isNotBlank(person.getDomainName()) ? person.getDomainName() : "");
                }
                dimensionNewsRanking.setReprintNum(person.getReprintNumb() - 1);
                if (StringUtils.isNotBlank(person.getAuthor())) {
                    dimensionNewsRanking.setDataAuthor(person.getAuthor());
                } else {
                    dimensionNewsRanking.setDataAuthor(
                            StringUtils.isNotBlank(person.getWebsiteName()) ? person.getWebsiteName() : "");
                }
                dimensionNewsRanking.setPublishTime(person.getReleaseTime());
                dimensionNewsRanking.setCountTime(fabuTime);
                dimensionNewsRanking.setUpdateTime(thisTime);
                DimensionNewsRankingList.add(dimensionNewsRanking);
            }
        }

        return DimensionNewsRankingList;
    }

    /**
     * 方案微信详细排行
     * 
     * @param entity
     * @param ifmIds
     * @param startTime
     * @param endTime
     * @return
     * @throws NumberErrorException
     */
    public List<DimensionWeixinRanking> StatisticsWeixinRanking(Class<?> entity, List<Integer> ifmIds, Long startTime,
            Long endTime) throws NumberErrorException {
        List<DimensionWeixinRanking> DimensionWeixinRankingList = new ArrayList<DimensionWeixinRanking>();// 方案新闻转载排行维度
        Date fabuTime = new Date(startTime);
        Date thisTime = new Date();
        // 循环方案ID
        for (Integer ifmId : ifmIds) {
            Query<?> query = getDatastore().createQuery(entity);
            query.criteria("ifmId").equal(ifmId.toString());
            query.criteria("articleType").equal("WeiXin");
            query.criteria("sort_timestamp").greaterThanOrEq(startTime);
            query.criteria("sort_timestamp").lessThan(endTime);
            // 聚合groupId取最热10条
            AggregationPipeline pipelineList = this.datastore.createAggregation(entity).match(query)
                    .group(Group.id(Group.grouping("groupId")), Group.grouping("groupId", Group.first("groupId")),
                            Group.grouping("articleId", Group.first("articleId")),
                            Group.grouping("releaseTime", Group.first("releaseTime")),
                            Group.grouping("readNumb", Group.first("readNumb")),
                            Group.grouping("pointNum", Group.first("pointNum")),
                            Group.grouping("title", Group.first("title")), Group.grouping("url", Group.first("url")),
                            Group.grouping("websiteName", Group.first("websiteName")),
                            Group.grouping("author", Group.first("author")),
                            Group.grouping("source", Group.first("source")),
                            Group.grouping("domainName", Group.first("domainName")),
                            Group.grouping("reprintNumb", new Accumulator("$sum", 1)))
                    .sort(Sort.descending("reprintNumb")).limit(10);
            Iterator<?> iteratorList = pipelineList.aggregate(entity,
                    AggregationOptions.builder().allowDiskUse(true).build());
            int i = 0;
            while (iteratorList.hasNext()) {
                InformationDistribute person = (InformationDistribute) iteratorList.next();
                i++;
                Query<?> query2 = getDatastore().createQuery(entity);
                query2.criteria("ifmId").equal(ifmId.toString());
                query2.criteria("sort_timestamp").greaterThanOrEq(startTime);
                query2.criteria("sort_timestamp").lessThan(endTime);
                query2.criteria("articleId").equal(person.getArticleId());
                InformationDistribute s = (InformationDistribute) query2.get();
                DimensionWeixinRanking dimensionWeixinRanking = new DimensionWeixinRanking();
                Long id = ReportUtils.buildId(fabuTime, ifmId, i);// 默认生成的每日ID
                dimensionWeixinRanking.setId(id);
                dimensionWeixinRanking.setPlanId(ifmId);
                dimensionWeixinRanking.setDataId(s.getId());
                dimensionWeixinRanking.setDataTitle(StringUtil.stringFilter(person.getTitle()));
                dimensionWeixinRanking.setDataUrl(person.getUrl());
                dimensionWeixinRanking
                        .setDomainName(StringUtils.isNotBlank(person.getDomainName()) ? person.getDomainName() : "");
                dimensionWeixinRanking.setReprintNum(person.getReprintNumb() - 1);
                dimensionWeixinRanking
                        .setViewNum(StringUtils.isNotBlank(person.getReadNumb().toString()) ? person.getReadNumb() : 0);
                dimensionWeixinRanking.setThumbNum(
                        StringUtils.isNotBlank(person.getPointNum().toString()) ? person.getPointNum() : 0);
                //person.getAuthor()为微信文章作者暂时没有数据和微信名称person.getSource()不同
                if (StringUtils.isNotBlank(person.getAuthor())) {
                    dimensionWeixinRanking.setDataAuthor(person.getSource());
                } else {
                	dimensionWeixinRanking.setDataAuthor(person.getSource());
                }
                /*暂时注释，如微信公众号作者出现
                if (StringUtils.isNotBlank(person.getAuthor())) {
                    dimensionWeixinRanking.setDataAuthor(person.getAuthor());
                } else {
                    dimensionWeixinRanking.setDataAuthor(
                            StringUtils.isNotBlank(person.getSource()) ? person.getSource() : "");
                }*/
                dimensionWeixinRanking.setPublishTime(person.getReleaseTime());
                dimensionWeixinRanking.setCountTime(fabuTime);
                dimensionWeixinRanking.setUpdateTime(thisTime);
                DimensionWeixinRankingList.add(dimensionWeixinRanking);
            }
        }

        return DimensionWeixinRankingList;
    }

    /**
     * 方案微博详细排行
     * 
     * @param entity
     * @param ifmIds
     * @param startTime
     * @param endTime
     * @return
     * @throws NumberErrorException
     */
    public List<DimensionWeiboRanking> StatisticsWeiboRanking(Class<?> entity, List<Integer> ifmIds, Long startTime,
            Long endTime) throws NumberErrorException {
        List<DimensionWeiboRanking> DimensionWeiboRankingList = new ArrayList<DimensionWeiboRanking>();// 方案微博转载排行维度
        Date fabuTime = new Date(startTime);
        Date thisTime = new Date();
        String WeiboContent = "";
        String WeibosourContent = "";
        // 循环方案ID
        for (Integer ifmId : ifmIds) {
            Query<?> query = getDatastore().createQuery(entity);
            query.criteria("ifmId").equal(ifmId.toString());
            query.criteria("articleType").equal("Micro");
            query.criteria("sort_timestamp").greaterThanOrEq(startTime);
            query.criteria("sort_timestamp").lessThan(endTime);
            // 聚合groupId取最热10条
            AggregationPipeline pipelineList = this.datastore.createAggregation(entity).match(query)
                    .group(Group.id(Group.grouping("groupId")), Group.grouping("groupId", Group.first("groupId")),
                            Group.grouping("articleId", Group.first("articleId")),
                            Group.grouping("releaseTime", Group.first("releaseTime")),
                            Group.grouping("weiboReprintNumb", Group.first("weiboReprintNumb")),
                            Group.grouping("weiboCommentNumb", Group.first("weiboCommentNumb")),
                            Group.grouping("weiboBlogger", Group.first("weiboBlogger")),
                            Group.grouping("weiboSourceBlogger", Group.first("weiboSourceBlogger")),
                            Group.grouping("weiboContent", Group.first("weiboContent")),
                            Group.grouping("url", Group.first("url")),
                            Group.grouping("websiteName", Group.first("websiteName")),
                            Group.grouping("domainName", Group.first("domainName")),
                            // Group.grouping("summary",
                            // Group.first("summary")),
                            Group.grouping("reprintNumb", new Accumulator("$sum", 1)))
                    .sort(Sort.descending("reprintNumb")).limit(10);
            Iterator<?> iteratorList = pipelineList.aggregate(entity,
                    AggregationOptions.builder().allowDiskUse(true).build());
            int i = 0;
            while (iteratorList.hasNext()) {
                InformationDistribute person = (InformationDistribute) iteratorList.next();
                i++;
                Query<?> query2 = getDatastore().createQuery(entity);
                query2.criteria("ifmId").equal(ifmId.toString());
                query2.criteria("sort_timestamp").greaterThanOrEq(startTime);
                query2.criteria("sort_timestamp").lessThan(endTime);
                query2.criteria("articleId").equal(person.getArticleId());
                InformationDistribute s = (InformationDistribute) query2.get();
                DimensionWeiboRanking dimensionWeiboRanking = new DimensionWeiboRanking();
                Long id = ReportUtils.buildId(fabuTime, ifmId, i);// 默认生成的每日ID
                dimensionWeiboRanking.setId(id);
                dimensionWeiboRanking.setPlanId(ifmId);
                dimensionWeiboRanking.setDataId(s.getId());
                // if
                // (StringUtils.isNotBlank(s.getSummary())&&"".equals(s.getSummary()))
                // {
                // dimensionWeiboRanking.setDataTitle(s.getSummary());
                // }
                if (StringUtils.isNotBlank(s.getWeiboSourceContent())
                        && !"None".equalsIgnoreCase(s.getWeiboSourceContent())) {
                    WeibosourContent = s.getWeiboSourceContent().replaceAll("<.*?em.*?>", "");
                    WeibosourContent = StringUtil.stringFilter(WeibosourContent);
                    dimensionWeiboRanking.setDataTitle(WeibosourContent);
                    ;
                } else if (StringUtils.isNotBlank(s.getWeiboContent())
                        && !"None".equalsIgnoreCase(s.getWeiboContent())) {
                    WeiboContent = s.getWeiboContent().replaceAll("<.*?em.*?>", "");
                    WeiboContent = StringUtil.stringFilter(WeiboContent);
                    dimensionWeiboRanking.setDataTitle(WeiboContent);
                } else {
                    dimensionWeiboRanking.setDataTitle("无");
                }
                dimensionWeiboRanking.setDataUrl(s.getUrl());
                if (StringUtils.isNotBlank(s.getDomainName())) {
                    dimensionWeiboRanking.setDomainName(s.getDomainName());
                } else {
                    dimensionWeiboRanking
                            .setDomainName(StringUtils.isNotBlank(s.getWebsiteName()) ? s.getWebsiteName() : "");
                }
                dimensionWeiboRanking.setReprintNum(person.getReprintNumb() - 1);

                dimensionWeiboRanking.setCommentNum(
                        StringUtils.isNotBlank(s.getWeiboCommentNumb().toString()) ? s.getWeiboCommentNumb() : 0);
                dimensionWeiboRanking.setRelayNum(
                        StringUtils.isNotBlank(s.getWeiboReprintNumb().toString()) ? s.getWeiboReprintNumb() : 0);

                if (StringUtils.isNotBlank(s.getWeiboBlogger())) {
                    dimensionWeiboRanking.setDataAuthor(s.getWeiboBlogger());
                } else {
                    dimensionWeiboRanking.setDataAuthor(
                            StringUtils.isNotBlank(s.getWeiboSourceBlogger()) ? s.getWeiboSourceBlogger() : "");
                }

                dimensionWeiboRanking.setPublishTime(s.getReleaseTime());
                dimensionWeiboRanking.setCountTime(fabuTime);
                dimensionWeiboRanking.setUpdateTime(thisTime);
                DimensionWeiboRankingList.add(dimensionWeiboRanking);
            }
        }

        return DimensionWeiboRankingList;
    }

    /**
     * 方案论坛详细排行
     * 
     * @param entity
     * @param ifmIds
     * @param startTime
     * @param endTime
     * @return
     * @throws NumberErrorException
     */
    public List<DimensionBbsRanking> StatisticsBbsRanking(Class<?> entity, List<Integer> ifmIds, Long startTime,
            Long endTime) throws NumberErrorException {
        List<DimensionBbsRanking> DimensionBbsRankingList = new ArrayList<DimensionBbsRanking>();// 方案论坛转载排行维度
        Date fabuTime = new Date(startTime);
        Date thisTime = new Date();
        // 循环方案ID
        for (Integer ifmId : ifmIds) {
            Query<?> query = getDatastore().createQuery(entity);
            query.criteria("ifmId").equal(ifmId.toString());
            query.criteria("articleType").equal("BBS");
            query.criteria("sort_timestamp").greaterThanOrEq(startTime);
            query.criteria("sort_timestamp").lessThan(endTime);
            // 聚合groupId取最热10条
            AggregationPipeline pipelineList = this.datastore.createAggregation(entity).match(query)
                    .group(Group.id(Group.grouping("groupId")),
                            Group.grouping("releaseTime", Group.first("releaseTime")),
                            Group.grouping("articleId", Group.first("articleId")),
                            Group.grouping("title", Group.first("title")), Group.grouping("url", Group.first("url")),
                            Group.grouping("websiteName", Group.first("websiteName")),
                            Group.grouping("replyNumb", Group.first("replyNumb")),
                            Group.grouping("readNumb", Group.first("readNumb")),
                            Group.grouping("author", Group.first("author")),
                            Group.grouping("domainName", Group.first("domainName")),
                            Group.grouping("reprintNumb", new Accumulator("$sum", 1)))
                    .sort(Sort.descending("reprintNumb")).limit(10);
            Iterator<?> iteratorList = pipelineList.aggregate(entity,
                    AggregationOptions.builder().allowDiskUse(true).build());
            int i = 0;
            while (iteratorList.hasNext()) {
                InformationDistribute person = (InformationDistribute) iteratorList.next();
                i++;
                Query<?> query2 = getDatastore().createQuery(entity);
                query2.criteria("ifmId").equal(ifmId.toString());
                query2.criteria("sort_timestamp").greaterThanOrEq(startTime);
                query2.criteria("sort_timestamp").lessThan(endTime);
                query2.criteria("articleId").equal(person.getArticleId());
                InformationDistribute s = (InformationDistribute) query2.get();
                DimensionBbsRanking dimensionBbsRanking = new DimensionBbsRanking();
                Long id = ReportUtils.buildId(fabuTime, ifmId, i);// 默认生成的每日ID
                dimensionBbsRanking.setId(id);
                dimensionBbsRanking.setPlanId(ifmId);
                dimensionBbsRanking.setDataId(s.getId());

                dimensionBbsRanking.setDataTitle(
                        StringUtils.isNotBlank(person.getTitle()) ? StringUtil.stringFilter(person.getTitle()) : "");

                dimensionBbsRanking.setDataUrl(person.getUrl());
                if (StringUtils.isNotBlank(person.getDomainName())) {
                    dimensionBbsRanking.setDomainName(person.getDomainName());
                } else {
                    dimensionBbsRanking.setDomainName(
                            StringUtils.isNotBlank(person.getWebsiteName()) ? person.getWebsiteName() : "");
                }
                dimensionBbsRanking.setReprintNum(person.getReprintNumb() - 1);
                if (StringUtils.isNotBlank(person.getAuthor())) {
                    dimensionBbsRanking.setDataAuthor(person.getAuthor());
                } else {
                    dimensionBbsRanking.setDataAuthor(
                            StringUtils.isNotBlank(person.getWebsiteName()) ? person.getWebsiteName() : "");
                }

                dimensionBbsRanking.setClickNum(
                        StringUtils.isNotBlank(person.getReadNumb().toString()) ? person.getReadNumb() : 0);
                dimensionBbsRanking.setReplyNum(
                        StringUtils.isNotBlank(person.getReplyNumb().toString()) ? person.getReplyNumb() : 0);

                dimensionBbsRanking.setPublishTime(person.getReleaseTime());
                dimensionBbsRanking.setCountTime(fabuTime);
                dimensionBbsRanking.setUpdateTime(thisTime);
                DimensionBbsRankingList.add(dimensionBbsRanking);
            }
        }

        return DimensionBbsRankingList;
    }

    public static void main(String[] args) {
        MongoHelper mongo = MongoHelper.getInstance();
        List<InformationDistribute> list = mongo.queryByIDlastTimestamp(InformationDistribute.class, "234", 0L);
        for (InformationDistribute informationDistribute : list) {
            System.out.println(informationDistribute);
        }
        // List<DimensionWeiboRanking> list = new ArrayList<>();
        // List<Integer> ifmIds = new ArrayList<>();
        // // ifmIds.add(263);
        // // ifmIds.add(266);
        // ifmIds.add(309);
        // // ifmIds.add(235);
        // try {
        // list = mongo.StatisticsWeiboRanking(InformationDistribute.class,
        // ifmIds, 1503158400000l, 1503244800000l);
        // } catch (NumberErrorException e) {
        // e.printStackTrace();
        // }
        // for (DimensionWeiboRanking DimensionWeiboRanking : list) {
        // System.out.println(DimensionWeiboRanking.toString());
        // }
        // Long i = System.currentTimeMillis();
        // mongo.queryContentBy_Id(InformationDistribute.class,"1b6705a728d1beef6d1eebe1a0a5e70d");
        // Long j = System.currentTimeMillis();
        // System.out.println(j-i+"ms");
        // InformationDistribute informationDistribute = new
        // InformationDistribute();
        // informationDistribute =
        // mongo.queryContentBy_Id(InformationDistribute.class,
        // "bc30aebf2bb104c9e1247e29090821ed");
        // System.out.println(informationDistribute.toString());

        // for (int i = 0; i < Channel.values().length; i++) {
        // System.out.println(Channel.values()[i] + "在枚举类型中的位置是" +
        // Channel.values()[i].ordinal());
        // }

    }

}
